##############################################################
## MOD Title:   Visual Confirmation for Cricca Guestbook
## MOD Author:    SemiX < michalski@teleos-web.de >
## MOD Description:
##	    This modification adds the phpBB visual confirmation mod to your guestbook.
##      It displays a dynamic generated image-code beside your form, which guests
##      have to confirm, if they want to add a new entry. It is a very effective
##      method to lock out spambots :P MOD can be disabled in AdminCP.
## MOD Version:		1.0.2
##
## Installation Level:	easy
## Installation Time:	10-15 Minutes
## Files To Edit:
##			guestbook.php
##			admin/admin_guestbook.php
##			includes/guestbook_class.php
##			includes/usercp_confirm.php
##			language/lang_english/lang_guestbook.php
##			language/lang_german/lang_guestbook.php
##			templates/subSilver/admin/guestbook_config_body.tpl
##			templates/subSilver/guestbook.tpl
##
##############################################################
## For Security Purposes, Please Check: http://www.phpbb.com/mods/ for the
## latest version of this MOD. Downloading this MOD from other sites could cause malicious code
## to enter into your phpBB Forum. As such, phpBB will not offer support for MOD's not offered
## in our MOD-Database, located at: http://www.phpbb.com/mods/
##############################################################
## Author Notes:
## This MOD bases on the Visual Confirmation Inst. Guide
## which is copyrighted by the following authors:
##    phpBB Group < N/A > (phpBB Group) http://www.phpbb.com/
##    ycl6 < ycl6@users.sourceforge.net > (Mac / Y.C. LIN) http://macphpbbmod.sourceforge.net/
##
## I just modified the main-part of the code to work with Cricca Guestbook, thats all. But i am not an
## experienced php-programmer, so you have to use this MOD on YOUR OWN RISK! But the changes I made are
## so small, there shouldn't be any bugs caused by myself :)
##############################################################
## MOD History:
##
##   2006-04-17 - Version 1.0.2
##      - Implemented security-fixes of phpBB 2.0.20
##	- merged guestbook_confirm.php with usercp_confirm.php
##	  (the code was quite the same, only the sql-query was different)
##
##   2006-02-15 - Version 1.0.1
##      - Forgot some html-code in guestbook.tpl. Yeah yeah, copy & paste *shame on me* 
##
##   2006-02-11 - Version 1.0.0
##      - Initial release
##
##############################################################
## Before Adding This MOD To Your Forum, You Should Back Up All Files Related To This MOD
##############################################################
#
#-----[ SQL ]------------------------------------------------
#
INSERT INTO phpbb_guest_config VALUES ('visual_confirm', '1');
CREATE TABLE `phpbb_guest_confirm` (
  `confirm_id` char(32) NOT NULL default '',
  `session_id` char(32) NOT NULL default '',
  `code` char(6) NOT NULL default '',
  PRIMARY KEY  (`session_id`,`confirm_id`)
) ENGINE=MyISAM;
#
#-----[ OPEN ]------------------------------------------------
#
guestbook.php
#
#-----[ FIND ]------------------------------------------------
#
		$mode = ( isset($HTTP_POST_VARS['mode']) ) ? $HTTP_POST_VARS['mode'] : $HTTP_GET_VARS['mode'];
		$mode = htmlspecialchars($mode);
#
#-----[ AFTER, ADD ]------------------------------------------
#
//-- mod : visual confirmation for cricca guestbook ------------------------------------------------
//-- add
  	if ( $mode == 'confirm' )
  	{
      $activate_cricca_guestbook = true;
      include($phpbb_root_path . 'includes/usercp_confirm.'.$phpEx);
    	exit;
  	}
//-- fin mod : visual confirmation for cricca guestbook --------------------------------------------
#
#-----[ FIND ]------------------------------------------------
#
if (isset($HTTP_POST_VARS['submit']))
{
  if (time() - $guest_book->decrypt($mode) > intval($guest_config['session_posting'])) die("Spaming attempt");
#
#-----[ AFTER, ADD ]------------------------------------------
#
//-- mod : visual confirmation for cricca guestbook ------------------------------------------------
//-- add
	if (!empty($guest_config['visual_confirm']) && !$userdata['session_logged_in'])
	{
		if (empty($HTTP_POST_VARS['confirm_id']))
		{
			$error = TRUE;
			$error_msg .= ( ( isset($error_msg) ) ? '<br />' : '' ) . $lang['Confirm_code_wrong'];
		}
		else
		{
			$confirm_id = htmlspecialchars($HTTP_POST_VARS['confirm_id']);
			$confirm_code= $HTTP_POST_VARS['confirm_code'];


			if (!preg_match('/^[A-Za-z0-9]+$/', $confirm_id))
			{
				$confirm_id = '';
			}

			$sql = 'SELECT code
				FROM ' . GUESTBOOK_CONFIRM_TABLE . "
				WHERE confirm_id = '$confirm_id'
					AND session_id = '" . $userdata['session_id'] . "'";
			if (!($result = $db->sql_query($sql)))
			{
				message_die(GENERAL_ERROR, 'Could not obtain confirmation code', __LINE__, __FILE__, $sql);
			}

			if ($row = $db->sql_fetchrow($result))
			{
				if ($row['code'] != $confirm_code)
				{
					$error = TRUE;
					$error_msg .= ( ( isset($error_msg) ) ? '<br />' : '' ) . $lang['Confirm_code_wrong'];
				}
				else
				{
					$sql = 'DELETE FROM ' . GUESTBOOK_CONFIRM_TABLE . "
						WHERE confirm_id = '$confirm_id'
							AND session_id = '" . $userdata['session_id'] . "'";
					if (!$db->sql_query($sql))
					{
						message_die(GENERAL_ERROR, 'Could not delete confirmation code', __LINE__, __FILE__, $sql);
					}
				}
			}
			else
			{
				$error = TRUE;
				$error_msg .= ( ( isset($error_msg) ) ? '<br />' : '' ) . $lang['Confirm_code_wrong'];
			}
			$db->sql_freeresult($result);
		}
	}
//-- fin mod : visual confirmation for cricca guestbook --------------------------------------------
#
#-----[ FIND ]------------------------------------------------
#
// standard page header
include($phpbb_root_path . 'includes/page_header.'.$phpEx);
#
#-----[ BEFORE, ADD ]-----------------------------------------
#
//-- mod : visual confirmation for cricca guestbook ------------------------------------------------
//-- add
	$confirm_image = '';
	if (!empty($guest_config['visual_confirm']) && !$userdata['session_logged_in'])
	{
		$sql = 'SELECT session_id
			FROM ' . SESSIONS_TABLE;
		if (!($result = $db->sql_query($sql)))
		{
			message_die(GENERAL_ERROR, 'Could not select session data', '', __LINE__, __FILE__, $sql);
		}

		if ($row = $db->sql_fetchrow($result))
		{
			$confirm_sql = '';
			do
			{
				$confirm_sql .= (($confirm_sql != '') ? ', ' : '') . "'" . $row['session_id'] . "'";
			}
			while ($row = $db->sql_fetchrow($result));

			$sql = 'DELETE FROM ' .  GUESTBOOK_CONFIRM_TABLE . "
				WHERE session_id NOT IN ($confirm_sql)";
			if (!$db->sql_query($sql))
			{
				message_die(GENERAL_ERROR, 'Could not delete stale confirm data', '', __LINE__, __FILE__, $sql);
			}
		}
		$db->sql_freeresult($result);

		$sql = 'SELECT COUNT(session_id) AS attempts
			FROM ' . GUESTBOOK_CONFIRM_TABLE . "
			WHERE session_id = '" . $userdata['session_id'] . "'";
		if (!($result = $db->sql_query($sql)))
		{
			message_die(GENERAL_ERROR, 'Could not obtain confirm code count', '', __LINE__, __FILE__, $sql);
		}

		if ($row = $db->sql_fetchrow($result))
		{
			if ($row['attempts'] > 35)
			{
				message_die(GENERAL_MESSAGE, $lang['Too_many_comments']);
			}
		}
		$db->sql_freeresult($result);

		// Generate the required confirmation code
		// NB 0 (zero) could get confused with O (the letter) so we make change it
		$code = dss_rand();
		$code = strtoupper(str_replace('0', 'o', substr($code, 6)));

		$confirm_id = md5(uniqid($user_ip));

		$sql = 'INSERT INTO ' . GUESTBOOK_CONFIRM_TABLE . " (confirm_id, session_id, code)
			VALUES ('$confirm_id', '". $userdata['session_id'] . "', '$code')";
		if (!$db->sql_query($sql))
		{
			message_die(GENERAL_ERROR, 'Could not insert new confirm code information', '', __LINE__, __FILE__, $sql);
		}

		unset($code);

		$confirm_image = (@extension_loaded('zlib')) ? '<img src="' . append_sid("guestbook.$phpEx?mode=confirm&amp;id=$confirm_id") . '" alt="" title="" />' : '<img src="' . append_sid("guestbook.$phpEx?mode=confirm&amp;id=$confirm_id&amp;c=1") . '" alt="" title="" /><img src="' . append_sid("guestbook.$phpEx?mode=confirm&amp;id=$confirm_id&amp;c=2") . '" alt="" title="" /><img src="' . append_sid("guestbook.$phpEx?mode=confirm&amp;id=$confirm_id&amp;c=3") . '" alt="" title="" /><img src="' . append_sid("guestbook.$phpEx?mode=confirm&amp;id=$confirm_id&amp;c=4") . '" alt="" title="" /><img src="' . append_sid("guestbook.$phpEx?mode=confirm&amp;id=$confirm_id&amp;c=5") . '" alt="" title="" /><img src="' . append_sid("guestbook.$phpEx?mode=confirm&amp;id=$confirm_id&amp;c=6") . '" alt="" title="" />';
		$s_hidden_fields .= '<input type="hidden" name="confirm_id" value="' . $confirm_id . '" />';

		$template->assign_block_vars('switch_confirm', array());
	}
//-- fin mod : visual confirmation for cricca guestbook --------------------------------------------
#
#-----[ FIND ]------------------------------------------------
#
$guest_book->guest_counter();

	$template->assign_vars(array(
#
#-----[ AFTER, ADD ]------------------------------------------
#
//-- mod : visual confirmation for cricca guestbook ------------------------------------------------
//-- add
	'CONFIRM_IMG' => $confirm_image,
	'L_CONFIRM_CODE_IMPAIRED'	=> sprintf($lang['Confirm_code_impaired'], '<a href="mailto:' . $board_config['board_email'] . '">', '</a>'),
	'L_CONFIRM_CODE' => $lang['Confirm_code'],
	'L_CONFIRM_CODE_EXPLAIN' => $lang['Confirm_code_explain'],
//-- fin mod : visual confirmation for cricca guestbook --------------------------------------------
#
#-----[ OPEN ]------------------------------------------------
#
admin/admin_guestbook.php
#
#-----[ FIND ]------------------------------------------------
#
$permit_mod_no = ( !$guest_config['permit_mod'] ) ? "checked=\"checked\"" : "";
#
#-----[ AFTER, ADD ]------------------------------------------
#
//-- mod : visual confirmation for cricca guestbook ------------------------------------------------
//-- add
$visual_confirm_yes = ( $guest_config['visual_confirm'] ) ? "checked=\"checked\"" : "";
$visual_confirm_no = ( !$guest_config['visual_confirm'] ) ? "checked=\"checked\"" : "";
//-- fin mod : visual confirmation for cricca guestbook --------------------------------------------
#
#-----[ FIND ]------------------------------------------------
#
  "L_RESET" => $lang['Reset'],
#
#-----[ AFTER, ADD ]------------------------------------------
#
//-- mod : visual confirmation for cricca guestbook ------------------------------------------------
//-- add
  "L_VISUAL_CONFIRM" => $lang['Visual_confirm'],
  "VISUAL_CONFIRM_YES" => $visual_confirm_yes,
  "VISUAL_CONFIRM_NO" => $visual_confirm_no,
//-- fin mod : visual confirmation for cricca guestbook --------------------------------------------
#
#-----[ OPEN ]------------------------------------------------
#
includes/guestbook_class.php
#
#-----[ FIND ]------------------------------------------------
#
define ('GUESTBOOK_CONFIG_TABLE', $table_prefix.'guest_config');
#
#-----[ AFTER, ADD ]------------------------------------------
#
//-- mod : visual confirmation for cricca guestbook ------------------------------------------------
//-- add
define ('GUESTBOOK_CONFIRM_TABLE', $table_prefix.'guest_confirm');
//-- fin mod : visual confirmation for cricca guestbook --------------------------------------------
#
#-----[ OPEN ]------------------------------------------------
#
includes/usercp_confirm.php
#
#-----[ FIND ]------------------------------------------------
#
$sql = 'SELECT code  
	FROM ' . CONFIRM_TABLE . " 
	WHERE session_id = '" . $userdata['session_id'] . "' 
		AND confirm_id = '$confirm_id'";
#
#-----[ REPLACE WITH ]----------------------------------------
#
//-- mod : visual confirmation for cricca guestbook ------------------------------------------------
//-- remove
// $sql = 'SELECT code  
//  FROM ' . CONFIRM_TABLE . " 
//  WHERE session_id = '" . $userdata['session_id'] . "' 
//	  AND confirm_id = '$confirm_id'";
//-- add
$table_name = ( $activate_cricca_guestbook ) ? GUESTBOOK_CONFIRM_TABLE : CONFIRM_TABLE;
$sql = 'SELECT code  
	FROM ' . $table_name . " 
	WHERE session_id = '" . $userdata['session_id'] . "' 
  		AND confirm_id = '$confirm_id'";
//-- fin mod : visual confirmation for cricca guestbook --------------------------------------------
#
#-----[ OPEN ]------------------------------------------------
#
language/lang_english/lang_guestbook.php
#
#-----[ FIND ]------------------------------------------------
#
//
// That's all Folks!
#
#-----[ BEFORE, ADD ]-----------------------------------------
#
//-- mod : visual confirmation for cricca guestbook ------------------------------------------------
//-- add
$lang['Too_many_comments'] = 'You have exceeded the number of posting-/viewing-attempts for this session. Please try again later.';
//-- fin mod : visual confirmation for cricca guestbook --------------------------------------------
#
#-----[ OPEN ]------------------------------------------------
#
language/lang_german/lang_guestbook.php
#
#-----[ FIND ]------------------------------------------------
#
//
// That's all Folks!
#
#-----[ BEFORE, ADD ]-----------------------------------------
#
//-- mod : visual confirmation for cricca guestbook ------------------------------------------------
//-- add
$lang['Too_many_comments'] = 'Du hast fr diese Session zu oft den falschen Besttigungscode eingegeben bzw. dir das Gstebuch angeschaut. Bitte versuche es spter nochmal.';
//-- fin mod : visual confirmation for cricca guestbook --------------------------------------------
#
#-----[ OPEN ]------------------------------------------------
#
templates/subSilver/admin/guestbook_config_body.tpl
#
#-----[ FIND ]------------------------------------------------
#
	<tr>
		<td class="row1">{N_VIEW_SMILE}<br /></td>
		<td class="row2"><input class="post" type="text" size="5" maxlength="4" name="smilies_row" value="{SMILIES_ROW}" />&nbsp;X&nbsp;<input class="post" type="text" size="5" maxlength="4" name="smilies_column" value="{SMILIES_COLUMN}" /></td>
	</tr>
#
#-----[ AFTER, ADD ]------------------------------------------
#
  <!-- Visual Confirmation -->
	<tr>
		<td class="row1">{L_VISUAL_CONFIRM}<br /></td>
		<td class="row2"><input type="radio" name="visual_confirm" value="1" {VISUAL_CONFIRM_YES} /> {L_YES}&nbsp;&nbsp;<input type="radio" name="visual_confirm" value="0" {VISUAL_CONFIRM_NO} /> {L_NO}</td>
	</tr>
#
#-----[ OPEN ]------------------------------------------------
#
templates/subSilver/guestbook.tpl
#
#-----[ FIND ]------------------------------------------------
#
                     {L_SITE}: <br />
                     <input type="text" value="{FIELD_SITO}" size="30" maxlength="100" class="post" name="sito" accesskey="s" tabindex="2" title="{L_SITE}" />
                     </span></td>
            </tr>
#
#-----[ REPLACE WITH ]----------------------------------------
#
                     {L_SITE}: <br />
                     <input type="text" value="{FIELD_SITO}" size="30" maxlength="100" class="post" name="sito" accesskey="s" tabindex="2" title="{L_SITE}" />
<!-- Visual Confirmation -->
<!-- BEGIN switch_confirm -->
                     <br />
                     {L_CONFIRM_CODE}:*<br />
                     <input type="text" class="post" name="confirm_code" size="30" maxlength="6" value="" />
<!-- END switch_confirm -->
                     </span></td>
            </tr>
<!-- Visual Confirmation -->
<!-- BEGIN switch_confirm -->
            <tr>
                     <td class="row1" width="100%">

                     <table border="0" width="100%" cellpadding="2" cellspacing="0">
                		<tr>
                			<td><span class="gensmall">*{L_CONFIRM_CODE_EXPLAIN}</span></td>
                		</tr>
                		<tr>
                			<td>{CONFIRM_IMG}</td>
                		</tr>
                		<tr>
                			<td><span class="gensmall">{L_CONFIRM_CODE_IMPAIRED}</span></td>
                		</tr>
                     </table>

                     </td>
            </tr>
<!-- END switch_confirm -->
#
#-----[ SAVE/CLOSE ALL FILES ]--------------------------------
#
# EoM